<?php

namespace App\Console\Commands\Test;

use Illuminate\Console\Command;
use App\Services\Bank\BankServiceManager;
use App\Models\Recharge;
use App\Models\BankDetailHangzhou;
use Carbon\Carbon;

class TestRechargeMatching extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'recharge:test-matching
                            {--create-test-data : 创建测试数据}
                            {--run-matching : 执行匹配算法}
                            {--show-results : 显示匹配结果}
                            {--cleanup : 清理测试数据}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '测试充值匹配算法功能';

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        $this->info('=== 充值匹配算法测试工具 ===');

        if ($this->option('create-test-data')) {
            $this->createTestData();
        }

        if ($this->option('run-matching')) {
            $this->runMatching();
        }

        if ($this->option('show-results')) {
            $this->showResults();
        }

        if ($this->option('cleanup')) {
            $this->cleanup();
        }

        if (!$this->option('create-test-data') &&
            !$this->option('run-matching') &&
            !$this->option('show-results') &&
            !$this->option('cleanup')) {
            $this->showHelp();
        }

        return 0;
    }

    /**
     * 创建测试数据
     */
    private function createTestData()
    {
        $this->info('创建测试数据...');

        // 创建测试充值申请
        $recharges = [
            [
                'amount' => 1000.00,
                'bank_name' => '中国银行',
                'bank_account' => '6217003810012345678',
                'landing_company' => '杭州测试公司',
                'remarks' => '测试充值1000元'
            ],
            [
                'amount' => 2500.50,
                'bank_name' => '建设银行',
                'bank_account' => '4367422812345678901',
                'landing_company' => '杭州测试公司',
                'remarks' => '测试充值2500.5元'
            ],
            [
                'amount' => 500.00,
                'bank_name' => '招商银行',
                'bank_account' => '6225882312345678',
                'landing_company' => '杭州测试公司',
                'remarks' => '测试充值500元'
            ]
        ];

        foreach ($recharges as $rechargeData) {
            $recharge = Recharge::create(array_merge($rechargeData, [
                'tenant_id' => 1,
                'status' => Recharge::STATUS_PENDING,
                'created_by' => 1,
                'updated_by' => 1
            ]));

            $this->line("创建充值申请: {$recharge->recharge_number} - {$recharge->amount}元");
        }

        // 创建对应的银行明细（模拟完全匹配、部分匹配、无匹配的情况）
        $bankDetails = [
            // 完全匹配
            [
                'serial_no' => 'TEST001' . time(),
                'serial_id' => 'ID001' . time(),
                'trans_date' => Carbon::now()->toDateString(),
                'trans_time' => Carbon::now()->toTimeString(),
                'transaction_datetime' => Carbon::now(),
                'bank_acc' => '6217003810012345678',
                'acc_name' => '杭州测试公司',
                'amt' => 1000.00,
                'bal' => 50000.00,
                'cd_sign' => '0',
                'opp_acc_name' => '张三',
                'opp_acc_no' => '6228481234567890',
                'opp_acc_bank' => '中国银行深圳分行',
                'abs' => '转账备注包含充值信息'
            ],
            // 金额略有差异的匹配
            [
                'serial_no' => 'TEST002' . time(),
                'serial_id' => 'ID002' . time(),
                'trans_date' => Carbon::now()->toDateString(),
                'trans_time' => Carbon::now()->addMinutes(10)->toTimeString(),
                'transaction_datetime' => Carbon::now()->addMinutes(10),
                'bank_acc' => '4367422812345678901',
                'acc_name' => '杭州测试公司',
                'amt' => 2500.00, // 少了0.5元
                'bal' => 52500.00,
                'cd_sign' => '0',
                'opp_acc_name' => '李四',
                'opp_acc_no' => '6225881234567890',
                'opp_acc_bank' => '建设银行上海分行',
                'abs' => '工资代发'
            ],
            // 时间差异较大的潜在匹配
            [
                'serial_no' => 'TEST003' . time(),
                'serial_id' => 'ID003' . time(),
                'trans_date' => Carbon::now()->subHours(25)->toDateString(),
                'trans_time' => Carbon::now()->subHours(25)->toTimeString(),
                'transaction_datetime' => Carbon::now()->subHours(25),
                'bank_acc' => '6225882312345678',
                'acc_name' => '杭州测试公司',
                'amt' => 500.00,
                'bal' => 53000.00,
                'cd_sign' => '0',
                'opp_acc_name' => '王五',
                'opp_acc_no' => '6225123456789012',
                'opp_acc_bank' => '招商银行广州分行',
                'abs' => '转账'
            ],
            // 干扰数据（支出明细）
            [
                'serial_no' => 'TEST004' . time(),
                'serial_id' => 'ID004' . time(),
                'trans_date' => Carbon::now()->toDateString(),
                'trans_time' => Carbon::now()->addMinutes(5)->toTimeString(),
                'transaction_datetime' => Carbon::now()->addMinutes(5),
                'bank_acc' => '6217003810012345678',
                'acc_name' => '杭州测试公司',
                'amt' => 800.00,
                'bal' => 49200.00,
                'cd_sign' => '1', // 支出
                'opp_acc_name' => '供应商A',
                'opp_acc_no' => '6228481234567891',
                'opp_acc_bank' => '工商银行',
                'abs' => '采购付款'
            ]
        ];

        foreach ($bankDetails as $detailData) {
            $detail = BankDetailHangzhou::create(array_merge($detailData, [
                'match_status' => 'unmatched',
                'sync_batch_id' => 'test_' . date('YmdHis'),
                'raw_data' => $detailData,
                'synced_at' => Carbon::now()
            ]));

            $cdSignText = $detail->cd_sign === '0' ? '收入' : '支出';
            $this->line("创建银行明细: {$detail->serial_no} - {$detail->amt}元 ({$cdSignText})");
        }

        $this->info('测试数据创建完成!');
    }

    /**
     * 执行匹配算法
     */
    private function runMatching()
    {
        $this->info('执行充值匹配算法...');

        $bankService = app(BankServiceManager::class);
        $result = $bankService->runRechargeMatching();

        if ($result['success']) {
            $this->info("匹配算法执行成功:");
            $this->line("- 总充值申请数: {$result['total_recharges']}");
            $this->line("- 成功匹配数: {$result['matched_count']}");
            $this->line("- 未匹配数: {$result['unmatched_count']}");
            $this->line("- 成功率: {$result['success_rate']}%");

            if (!empty($result['matches'])) {
                $this->info("\n匹配详情:");
                foreach ($result['matches'] as $match) {
                    $status = $match['status'] === 'matched' ? '✓ 已匹配' : '✗ 未匹配';
                    $confidence = isset($match['confidence']) ? sprintf('%.2f', $match['confidence']) : '0.00';
                    $this->line("  充值单号: {$match['recharge_number']} - {$status} (置信度: {$confidence})");
                }
            }
        } else {
            $this->error("匹配算法执行失败: " . ($result['error'] ?? '未知错误'));
        }
    }

    /**
     * 显示匹配结果
     */
    private function showResults()
    {
        $this->info('当前匹配状态:');

        // 显示充值申请状态
        $recharges = Recharge::whereIn('status', [
            Recharge::STATUS_PENDING,
            Recharge::STATUS_PROCESSING,
            Recharge::STATUS_MATCHED,
            Recharge::STATUS_CONFIRMED
        ])->get();

        if ($recharges->isEmpty()) {
            $this->line('暂无充值申请数据');
        } else {
            $this->info("\n充值申请状态:");
            foreach ($recharges as $recharge) {
                $statusMap = [
                    Recharge::STATUS_PENDING => '待处理',
                    Recharge::STATUS_PROCESSING => '处理中',
                    Recharge::STATUS_MATCHED => '已匹配',
                    Recharge::STATUS_CONFIRMED => '已确认'
                ];
                $status = $statusMap[$recharge->status] ?? $recharge->status;
                $this->line("  {$recharge->recharge_number}: {$recharge->amount}元 - {$status}");
            }
        }

        // 显示银行明细状态
        $details = BankDetailHangzhou::whereIn('match_status', ['unmatched', 'matched'])
            ->orderBy('transaction_datetime', 'desc')
            ->get();

        if ($details->isEmpty()) {
            $this->line('暂无银行明细数据');
        } else {
            $this->info("\n银行明细状态:");
            foreach ($details as $detail) {
                $statusMap = [
                    'unmatched' => '未匹配',
                    'matched' => '已匹配',
                    'ignored' => '已忽略'
                ];
                $status = $statusMap[$detail->match_status] ?? $detail->match_status;
                $matchInfo = $detail->matched_recharge_id ? " (匹配充值ID: {$detail->matched_recharge_id})" : '';
                $this->line("  {$detail->serial_no}: {$detail->amt}元 - {$status}{$matchInfo}");
            }
        }
    }

    /**
     * 清理测试数据
     */
    private function cleanup()
    {
        $this->info('清理测试数据...');

        // 删除测试的充值申请
        $deletedRecharges = Recharge::where('recharge_number', 'like', 'RECHARGE%')
            ->where('created_at', '>=', Carbon::now()->subHour())
            ->delete();

        // 删除测试的银行明细
        $deletedDetails = BankDetailHangzhou::where('sync_batch_id', 'like', 'test_%')
            ->orWhere('serial_no', 'like', 'TEST%')
            ->delete();

        $this->info("清理完成: 删除了 {$deletedRecharges} 个充值申请和 {$deletedDetails} 个银行明细");
    }

    /**
     * 显示帮助信息
     */
    private function showHelp()
    {
        $this->info('使用示例:');
        $this->line('php artisan recharge:test-matching --create-test-data  # 创建测试数据');
        $this->line('php artisan recharge:test-matching --run-matching     # 执行匹配算法');
        $this->line('php artisan recharge:test-matching --show-results     # 显示匹配结果');
        $this->line('php artisan recharge:test-matching --cleanup          # 清理测试数据');
        $this->line('');
        $this->line('完整测试流程:');
        $this->line('1. php artisan recharge:test-matching --create-test-data');
        $this->line('2. php artisan recharge:test-matching --run-matching');
        $this->line('3. php artisan recharge:test-matching --show-results');
        $this->line('4. php artisan recharge:test-matching --cleanup');
    }
}